//
//  SFCClientTypes.h
//  SVNForCocoa
//
//  Created by Jeremy Pereira on 11/01/2014.
//  Copyright (c) 2014 Jeremy Pereira. All rights reserved.
//
/*!
 *    @file
 *    @brief Client types for SFCLib
 *
 *    This file contains the list of traditional C types and enums for the 
 *    SFCClient.  These types are put here mainly because the SFCClient.h file
 *    was becoming unmaneagable.
 */
#import <Foundation/Foundation.h>

@class SFCCommitInfo;
@class SFCLogEntry;
@class SFCStatusEntry;
@class SFCIODirectoryEntry;
@class SFCDirectoryEntry;
@class SFCLock;
@class SFCWCNotification;
@class SFCConflictResult;
@class SFCConflictDescription;

/*!
 *    @brief Revision number.
 *
 *    This is for Subversion repository revision numbers.  We define it here
 *    because we don't want to pollute the public interface with the svn
 *    headers.
 */
typedef long int SFCRevNum;

/*!
 *    @brief Depth for tree based operations.
 *
 *    The values of these will correspond to the values of @c svn_depth_t
 */
enum SFCDepth
{
	/*!
	 *    @brief Unknown or ignored depth.
     *
     *    In some contexts, this means the client will guess an appropriate
     *    depth.
	 */
	SFC_DEPTH_UNKNOWN = -2,
    /*!
     *    @brief Exclude a directory.
     *
     *    This depth is not used for anything client side.
     */
    SFC_DEPTH_EXCLUDE,
    /*!
     *    @brief Jut the named directory, nothing inside it.
     */
    SFC_DEPTH_EMPTY,
    /*!
     *    @brief The named directory + files (not directories) inside it.
     */
    SFC_DEPTH_FILES,
    /*!
     *    @brief THe named directory and all of its immediate children.
     *
     *    Any child directories will behave as if the dpeth is SFC_DEPTH_EMPTY.
     */
    SFC_DEPTH_IMMEDIATES,
	/*!
	 *    @brief recursively include everything below the directory.
	 */
    SFC_DEPTH_INFINITY,
};

/*!
 *    @brief A typedef for the SFCDepth enumeration.
 */
typedef enum SFCDepth SFCDepth;

/*!
 *    @brief Changed path actions.
 *    @todo Document actions properly.
 */
enum SFCLCPAction
{
    SFC_LPC_ACTION_ADD = 'A',
    SFC_LPC_ACTION_DELETE = 'D',
    SFC_LPC_ACTION_REPLACE = 'R',
    SFC_LPC_ACTION_MODIFY = 'M',
};

/*!
 *    @brief A typedef for the SFCLCPAction enum
 */
typedef enum SFCLCPAction SFCLCPAction;

/*!
 *    @brief Node kind
 *
 *    This must have the same values as svn_node_kind_t
 */
enum SFCNodeKind
{
	/*!
	 *    @brief This is not a node.
	 */
	SFC_NODE_KIND_NONE,
    /*!
     *    @brief This is a file.
     */
    SFC_NODE_KIND_FILE,
    /*!
     *    @brief This is a directory.
     */
    SFC_NODE_KIND_DIRECTORY,
    /*!
     *    @brief TWe don't know what kind this is.
     */
    SFC_NODE_KIND_UNKNOWN,
    /*!
     *    @brief A symlink.
     *
     *    As of svn 1.8, this value is not used by the client libraries.
     */
    SFC_NODE_KIND_SYM_LINK,
};

typedef enum SFCNodeKind SFCNodeKind;

/*!
 *    @brief Working copy status of a status item.
 *
 *    The values must correspond to svn_wc_status_kind
 */
enum SFCWCStatusKind
{
	/*!
	 *    @brief Does not exist.
	 */
	SFC_WC_STATUS_NONE = 1,
	/*!
	 *    @brief Is not a versioned thing in this working copy.
	 */
    SFC_WC_STATUS_UNVERSIONED,
	/*!
	 *    @brief Exists but nothing out of the ordinary.
	 */
    SFC_WC_STATUS_NORMAL,
    /*!
	 *    @brief Scheduled for addition to the repository.
	 */
    SFC_WC_STATUS_ADDED,
	/*!
	 *    @brief Exists in the repository but missing from the working copy.
	 */
    SFC_WC_STATUS_MISSING,
    /*!
     *    @brief Scheduled for deleteion.
     */
    SFC_WC_STATUS_DELETED,
    /*!
	 *    @brief Was deleted but readded.
	 */
    SFC_WC_STATUS_REPLACED,
	/*!
	 *    @brief Has been modified.
	 */
    SFC_WC_STATUS_MODIFIED,
	/*!
	 *    @brief Has been merged - not used apparently.
	 */
    SFC_WC_STATUS_MERGED,
	/*!
	 *    @brief Is conflicted.
	 */
    SFC_WC_STATUS_CONFLICTED,
	/*!
	 *    @brief Is unversioned but also in the ifgnore list.
	 */
    SFC_WC_STATUS_IGNORED,
    /*!
	 *    @brief An unversioned resource is in the way of the versioned resource.
	 */
    SFC_WC_STATUS_OBSTRUCTED,
	/*!
	 *    @brief Is an external.
	 */
    SFC_WC_STATUS_EXTERNAL,
	/*!
	 *    @brief A directory with an incomplete entry list.
	 */
    SFC_WC_STATUS_INCOMPLETE,
};

typedef enum SFCWCStatusKind SFCWCStatusKind;

/*!
 *    @brief Various boolean commit options.
 */
enum SFCCommitOptions
{
	/*!
	 *    @brief If set, the commit will not release locks that are held.
	 */
	SFCCommitOptionKeepLocks = 1,
    /*!
     *    @brief If set, the commit will disassociate the change lists from the
     *           targets.
     */
    SFCCommitOptionKeepChangeLists = 2,
    /*!
     *    @brief If true, changes to descendants are only committed when they are
     *           included via depth or targets.
     */
    SFCCommitOptionCommitAsOperations = 4,
    /*!
     *    @brief If true include file externals in the commit.
     */
    SFCCommitOptionIncludeFileExternals = 8,
    /*!
     *    @brief If true include directory externals.
     */
    SFCCommitOptionIncludeDirectoryExternals = 16,
};

/*!
 *    @brief Various boolean log options.
 */
enum SFCLogOptions
{
    /*!
     *    @brief If set, the changedPaths of the SFCLogEntry will be populated.
     */
    SFC_LOG_OPTION_DISCOVER_CHANGED_PATHS = 1,
	/*!
	 *    @brief If set, copy history for each target will not be harvested.
	 */
	SFC_LOG_OPTION_STRICT_NODE_HISTORY = 2,
    /*!
     *    @brief If set, history for revisions that have been merged to target
     *           will be returned.
     */
    SFC_LOG_OPTION_INCLUDE_MERGED_REVISIONS = 4,
};

/*!
 *    @brief Various boolean options for a status invocation.
 */
enum SFCStatusOptions
{
	/*!
	 *    @brief retrieve all entries.
	 *
	 *    If set, this will retrieve info about everything that qualifies from
     *    the path, depth and change list filter.  Otherwise, retrieve only
     *    "interesting" entries (local mods and/or out of date).
	 */
	SFC_STATUS_OPTION_GET_ALL = 1,
    /*!
     *    @brief Contact the server to get further info.
     *
     *    If set, the server will be contacted and the working copy will be
     *    compared against the given revision to see if it is out of date.
     *    If it is set and resultRevision is non NULL, the actual revision
     *    compared against will be returned.
     */
    SFC_STATUS_OPTION_UPDATE = 2,
    /*!
     *    @brief If set, svn:ignore property will be ignored i.e. ignored items
     *           will be reported as ignored instead of omitted.
     */
    SFC_STATUS_OPTION_NO_IGNORE = 4,
    /*!
     *    @brief If set, ignore externals.
     */
    SFC_STATUS_OPTION_IGNORE_EXTERNALS = 8,
    /*!
     *    @brief If set and depth is not SFC_DEPTH_UNKNOWN, then the status is
     *           calculated as if depth_is_sticky was passed to an equivalent
     *           update command.
     */
    SFC_STATUS_OPTION_DEPTH_AS_STICKY = 16,
};

/*!
 *    @brief Options for an update operation.
 */
enum SFCUpdateOptions
{
	/*!
	 *    @brief If set and not SFC_DEPTH_UNKNOWN, set the paths' sticky depths
 	 */
	SFC_UPDATE_OPTION_DEPTH_IS_STICKY = 1,
    /*!
     *    @brief Don't process externals in the working copy.
     */
    SFC_UPDATE_OPTION_IGNORE_EXTERNALS = 2,
    /*!
     *    @brief If set, unversioned obstructions are left as is and treated as
     *           user modifications.
     */
    SFC_UPDATE_OPTION_ALLOW_UNVERSIONED_OBSTRUCTIONS = 4,
    /*!
     *    @brief If set, a local addition with the same path as an add is
     *           treated as a normal node instead of a conflict.
     */
    SFC_UPDATE_OPTION_ADDS_AS_MODIFICATION = 8,
    /*!
     *    @brief Idf set, create non existent parent paths.
     */
    SFC_UPDATE_OPTION_MAKE_PARENTS = 16,

};

/*!
 *    @brief Options for an add operation.
 */
enum SFCAddOptions
{
	/*!
	 *    @brief If set, do not error on already verioned items.
	 *
	 *    If used on a directory with a depth of infinity, this will schedule
     *    any unversioned files in that directory for addition.
	 */
	SFC_ADD_FORCE = 1,
    /*!
     *    @brief If set, the svn:ignore property is ignored.
     */
    SFC_ADD_NO_IGNORE = 2,
    /*!
     *    @brief If set then auto properties from te client context are ignored.
     */
    SFC_ADD_NO_AUTOPROPS = 4,
    /*!
     *    @brief If set, any unversioned directories in the path will also be
     *           added.
     */
    SFC_ADD_ADD_PARENTS = 8,
};

/*!
 *    @brief Boolean options to send to a diff.
 */
enum SFCDiffOptions
{
	/*!
	 *    @brief Ignore relatedness of the two files.
	 *
	 *    Use ignore_ancestry to control whether or not items being diffed will
     *    be checked for relatedness first. Unrelated items are typically
     *    transmitted to the editor as a deletion of one thing and the addition
     *    of another, but if this flag is TRUE, unrelated items will be diffed
     *    as if they were related.
	 */
	SFC_DIFF_IGNORE_ANCESTRY = 1,
    /*!
     *    @brief No diff output for files that have been added.
     */
    SFC_DIFF_NO_DIFF_ADDED = 2,
    /*!
     *    @brief No diff output for files that have been deleted.
     */
    SFC_DIFF_NO_DIFF_DELETED = 4,
    /*!
     *    @brief Copied files are not diffed against source and treated as if
     *           they were new adds.
     */
    SFC_DIFF_SHOW_COPIES_AS_ADDS = 8,
    /*!
     *    @brief If set, generate diff output for binary files (binary files are
     *           usually ignored).
     */
    SFC_DIFF_IGNORE_CONTENT_TYPE = 16,
    /*!
     *    @brief Don't diff properties.
     */
    SFC_DIFF_IGNORE_PROPERTIES = 32,
    /*!
     *    @brief Only diff properties - mutually exclusive with SFC_IGNORE_PROPERTIES
     */
    SFC_DIFF_PROPERTIES_ONLY = 64,
    /*!
     *    @brief Produce output in Git format.
     */
    SFC_DIFF_USE_GIT_FORMAT = 128,
};

/*!
 *    @brief Typedef for a block called on successful commits.
 *
 *    This is a block used when a commit operation completes successfully.
 *
 *    @param commitInfo Object containing information about the commit.
 *
 *    @return true unless something goes wrong.
 */
typedef bool (^SFCCommittedBlock)(SFCCommitInfo* commitInfo);

/*!
 *    @brief Typedef for a block to be called to process log entries during
 *           the log:... method.
 *
 *    @param logInfo SFCLogEntry describing the properties of the log entry.
 *
 *    @return true for success.
 */
typedef bool (^SFCLogBlock)(SFCLogEntry* logInfo);
/*!
 *    @brief Typedef for a block to be called to proess status entries during
 *           the status:... method.
 *
 *    @param path       Path to which  the status entry relates.
 *    @param statusInfo object describing the status entry.
 *
 *    @return true for success, false for failure.
 */
typedef bool (^SFCStatusBlock)(NSString* path, SFCStatusEntry* statusInfo);

/*!
 *    @brief Block used in commit operations to retrieve the log message.
 *
 *    @param commitItems  Array of SFCCommitItems that are in this commit.
 *    @param logMessage   Pointer to place to put the log message.
 *    @param tempFilePath Fill in with a path to the saved commit message if you
 *                        like.
 *    @return true if log message retrieved, false if the commit should be
 *            aborted.
 */
typedef bool (^SFCGetCommitLog)(NSArray* commitItems,
                                NSString* __autoreleasing* logMessage,
                                NSString* __autoreleasing* tempFilePath);

/*!
 *    @brief Block for processing blame lines.
 *
 *    Start and end revisions refer to the whole blame range.  Knowing these
 *    might help with formatting output.  The merged- parameters will only be
 *    valid if the blame was initiated with includeMergedRevisions set to true.
 *
 *    @param startRevision       Start revision of the range covered by the
 *                               whole blame operation
 *    @param endRevision         End revision of the range covered by the whole
 *                               blame operation.
 *    @param lineNumber          Line number of this blame item.
 *	  @param revision            Revision at which this line was last changed.
 *    @param revProperties       Revision properties for the line's revision.
 *    @param mergedRevision      Revision of merged change.
 *    @param mergedRevProperties Rev properties for a merged change.
 *    @param mergedPath          Path of merge.
 *    @param line                The text of the line.
 *    @param localChange         Will be true if there is a local change.
 *
 *    @return false if something goes wrong, true if it is all hunkey dorey.
 */
typedef bool (^SFCBlameBlock)(SFCRevNum startRevision,
                                  SFCRevNum endRevision,
                                  int64_t lineNumber,
                                  SFCRevNum revision,
                                  NSDictionary* revProperties,
                                  SFCRevNum mergedRevision,
                                  NSDictionary* mergedRevProperties,
                                  NSString* mergedPath,
                                  NSString* line,
                                  bool localChange);

/*!
 *    @brief Block to use in a list operation.
 *
 *    @param path            Path of directory entry relative to the absolute
 *                           path.
 *    @param directoryEntry  Information about the directory entry.
 *    @param lock            The lock, if there is one and it has been requested.
 *    @param absolutePath    The path in the repo for which the list was requested.
 *    @param externParentURL The URL of the top level of an extern
 *    @param externTarget    The path of the target relative to the extern URL.
 *
 *    @return true if it worked, false otherwise
 */
typedef bool (^SFCListBlock)(NSString* path,
                             SFCDirectoryEntry* directoryEntry,
                             SFCLock* lock,
                             NSString* absolutePath,
                             NSURL* externParentURL,
                             NSString* externTarget);
/*!
 *    @brief Typedef for notify block called by the client during all sorts of
 *           actions.
 *
 *    @param notification Object with notiufication information.
 */
typedef void (^SFCClientNotifyBlock)(SFCWCNotification* notification);

/*!
 *    @brief Block called by list properties.
 *
 *    @param path                Path to which this block applies.
 *    @param properties          properties of the path.
 *    @param inheritedProperties Inherited properties of the path.
 *
 *    @return true for success, false for failure.
 */
typedef bool (^SFCPropListBlock)(NSString* path,
                                NSDictionary* properties,
                                NSArray* inheritedProperties);

/*!
 *    @brief Import filter callback
 *
 *    When doing an import, this block is called for each item to allow you to
 *    do fine grained filtering on items to import.
 *
 *    @param path           Path of the item.
 *    @param directoryEntry Directory entry representing the item.
 *    @param errorOccurred  If an error occurs, set this to true to make the 
 *                          import stop.
 *
 *    @return <#return value description#>
 */
typedef bool (^SFCImportFilter)(NSString* path,
                                SFCIODirectoryEntry* directoryEntry,
                                bool* errorOccurred);

/*!
 *    @brief Ignore space options
 *    @todo Need a unit test to ensure these are the same as
 *          svn_diff_file_ignore_space_t values
 */
typedef enum SFCDiffFileIgnoreSpace
{
	/*!
	 *    @brief Do not ignore white space.
	 */
	SFC_DIFF_IGNORE_SPACE_NONE,
	/*!
	 *    @brief Ignore different sequences of white space
	 *
	 *    All sequences of white spaces are treated as if they are a single char
     *    32.
	 */
	SFC_DIFF_IGNORE_SPACE_CHANGE,
	/*!
	 *    @brief Ignore all white space characters.
	 */
	SFC_DIFF_IGNORE_SPACE_ALL
} SFCDiffFileIgnoreSpace;

/*!
 *    @brief Options used when copying files or directories.
 *
 *    These can be or'd together to set multiple options.
 */
typedef enum SFCCopyOption
{
	/*!
	 *    @brief Controls whether the sources are copied as children of the
     *           destination or as the destination.
	 *
	 *    If sources has only one item, attempt to copy it to dst_path. If
     *    SFC_COPY_OPTION_COPY_AS_CHILD is set and dst_path already exists,
     *    attempt to copy the item as a child of dst_path. If
     *    SFC_COPY_OPTION_COPY_AS_CHILD is FALSE and dst_path already exists,
     *    fail.
     *
     *    If sources has multiple items SFC_COPY_OPTION_COPY_AS_CHILD must be
     *    set.
	 */
	SFC_COPY_OPTION_COPY_AS_CHILD = 1,
	/*!
	 *    @brief Make necessary parents to create the destination.
	 */
	SFC_COPY_OPTION_MAKE_PARENTS = 2,
	/*!
	 *    @brief Don't copy externals.
	 */
	SFC_COPY_OPTION_IGNORE_EXTERNALS = 4,

} SFCCopyOption;

/*!
 *    @brief Options that can be set on an import
 */
typedef enum SFCImportOption
{
	/*!
	 *    @brief Don't ignore items that would otherwise match the ignore rules.
	 */
	SFC_IMPORT_OPTION_NO_IGNORE = 1,
    /*!
     *    @brief Don't apply any autoproperties.
     */
    SFC_IMPORT_OPTION_NO_AUTOPROPS = 2,
    /*!
     *    @brief Ignore unknown node types e.g. device files and unix pipes.
     */
    SFC_IMPORT_OPTION_IGNORE_UNKNOWN_NODE_TYPES = 4
} SFCImportOption;

/*!
 *    @brief Options for exporting parts of the repo tree.
 *
 *    Options can be or'd together.
 */
typedef enum SFCExportOption
{
	/*!
	 *    @brief Overwrite target directories and files if they already exist.
	 */
	SFC_EXPORT_OPTION_OVERWRITE = 1,
    /*!
     *    @brief Don't export externs.
     */
    SFC_EXPORT_OPTION_IGNORE_EXTERNALS = 2,
    /*!
     *    @brief Don't expand SVN keywords.
     */
    SFC_EXPORT_OPTION_IGNORE_KEYWORDS = 4
} SFCExportOption;

/*!
 *    @brief Merge options
 *
 *    Options can be or'd together.
 */
typedef enum SFCMergeOption
{
	/*!
	 *    @brief disable merge tracking, by treating the two sources as 
     *           unrelated even if they actually have a common ancestor.
	 */
	SFC_MERGE_OPTION_IGNORE_MERGE_INFO = 1,
    /*!
     *    @brief diff unrelated nodes as if related: that is, diff the 'left' 
     *           and 'right' versions of a node as if they were related (if they 
     *           are the same kind) even if they are not related.
     */
    SFC_MERGE_OPTION_DIFF_IGNORE_ANCESTRY = 2,
    /*!
     *    @brief If the merge involves deleting a file whose content differs 
     *           from the source-left version, or a locally modified directory, 
     *           or an unversioned item, then the operation will fail, unless 
     *           this is set (in which case the item will be deleted).
     */
    SFC_MERGE_OPTION_FORCE_DELETE = 4,
    /*!
     *    @brief the merge is performed, but is limited only to mergeinfo 
     *           property changes on existing paths in target_wcpath.
     */
    SFC_MERGE_OPTION_RECORD_ONLY = 8,
    /*!
     *    @brief the merge is carried out, and full notification feedback is 
     *           provided, but the working copy is not modified.
     */
    SFC_MERGE_OPTION_DRY_RUN = 16,
    /*!
     *    @brief If set, will allow the user to merge into a mied revision 
     *           working copy.
     */
    SFC_MERGE_OPTION_ALLOW_MIXED_REVISIONS = 32
}
SFCMergeOption;

/*!
 *    @brief Options for an svn move.
 *
 *    Options can be or'd together.
 */
typedef enum SFCMoveOption
{
    /*!
     *    @brief If set, will attempt to move to the destination as a child of
     *           the destination.
     */
    SFC_MOVE_OPTION_MOVE_AS_CHILD = 1,
    /*!
     *    @brief Makes any non existent parent directories in the destination
     *           path.
     */
    SFC_MOVE_OPTION_MAKE_PARENTS = 2,
    /*!
     *    @brief Allows the move to work if the sources are a mixed revision
     *           working copy.
     */
    SFC_MOVE_OPTION_ALLOW_MIXED_REVISIONS = 4,
    /*!
     *    @brief Moves only the metadata in a working copy.
     */
    SFC_MOVE_OPTION_META_DATA_ONLY = 8
} SFCMoveOption;

/*!
 *    @brief Options for the patch method.
 *
 *    Options may be or'd together.
 */
typedef enum SFCPatchOption
{
	SFC_PATCH_OPTION_DRY_RUN = 1,
    SFC_PATCH_OPTION_REVERSE = 2,
    SFC_PATCH_OPTION_IGNORE_WHITE_SPACE = 4,
    SFC_PATCH_OPTION_REMOVE_TEMP_FILES = 8
} SFCPatchOption;

/*!
 *    @brief Typedef for the callback block for patching.
 *
 *    Invoked by patch before attempting to patch the file at
 *    canonicalPathFromPatchFile.
 *
 *    @param canonicalPathFromPatchFile The path from the patch file to be 
 *                                      patched, but canonicalised.
 *    @param absolutePath               A temp file containing the result of the
 *                                      patch.
 *    @param rejectAbsolutePath         Temp file containing any hunks that have
 *                                      been rejected.
 *    @param errorOccurred              Set to true if something went wrong and
 *                                      you want the patch to stop.
 *
 *    @return true if you want the patch on this file to go ahead.  False if you
 *            want the patch for the file to be rejected.
 */
typedef bool (^SFCPatchBlock)(NSString* canonicalPathFromPatchFile,
                              NSString* absolutePath,
                   			  NSString* rejectAbsolutePath,
                              bool* errorOccurred);

/*!
 *    @brief Choices of ways to resolve (or not) a conflict.
 *
 *    <#Description#>
 */
typedef enum SFCConflictChoice
{
    /*!
     *    @brief Postpone resolution till later.
     */
    SFC_CONFLICT_CHOICE_POSTPONE,
	/*!
	 *    @brief Take the base from the working copy.
	 */
	SFC_CONFLICT_CHOICE_BASE,
    /*!
     *    @brief Take the whole of the incoming node.
     */
    SFC_CONFLICT_CHOICE_THEIRS_FULL,
    /*!
     *    @brief Take the whole of the working copy node.
     */
    SFC_CONFLICT_CHOICE_MINE_FULL,
    /*!
     *    @brief Use incoming where there are conflicts.
     */
    SFC_CONFLICT_CHOICE_THEIRS_CONFLICT,
    /*!
     *    @brief Use working copy where there are conflicts.
     *
     */
    SFC_CONFLICT_CHOICE_MINE_CONFLICT,
    /*!
     *    @brief Use the merrged file.
     */
    SFC_CONFLICT_CHOICE_MERGED,
    /*!
     *    @brief Don't know.
     *
     *    Used on automatic merges to make the resolver use a callback block.
     */
    SFC_CONFLICT_CHOICE_UNSPECIFIED,
}
SFCConflictChoice;

/*!
 *    @brief Block for interactively resolving conflicts.
 *
 *    @param conflict Description of the conflict to resolve.
 *
 *    @return A conflict result or nil if something goes wrong.
 */
typedef SFCConflictResult* (^SFCConfictResolverBlock)(SFCConflictDescription* conflict);

/*!
 *    @brief Kind of conflict used by conflict resolution blocks.
 */
typedef enum SFCConflictKind
{
    SFC_CONFLICT_KIND_TEXT,
    SFC_CONFLICT_KIND_PROPERTY,
    SFC_CONFLICT_KIND_TREE
} SFCConflictKind;

/*!
 *    @brief Action being attempted when a conflict occurred.
 */
typedef enum SFCConflictAction
{
    SFC_CONFLICT_ACTION_EDIT,
    SFC_CONFLICT_ACTION_ADD,
    SFC_CONFLICT_ACTION_DELETE,
    SFC_CONFLICT_ACTION_REPLACE
} SFCConflictAction;

/*!
 *    @brief The pre-existing reason that caused a state of conflict.
 */
typedef enum SFCConflictReason
{
    SFC_CONFLICT_REASON_EDITED,
    SFC_CONFLICT_REASON_OBSTRUCTED,
    SFC_CONFLICT_REASON_DELETED,
    SFC_CONFLICT_REASON_MISSING,
    SFC_CONFLICT_REASON_UNVERSIONED,
    SFC_CONFLICT_REASON_ADDED,
    SFC_CONFLICT_REASON_REPLACED,
    SFC_CONFLICT_REASON_MOVED_AWAY,
    SFC_CONFLICT_REASON_MOVED_HERE,
} SFCConflictReason;

/*!
 *    @brief The user operation that is being performed to cause a conflict.
 */
typedef enum SFCOperation
{
    SFC_OPERATION_NONE,
    SFC_OPERATION_UPDATE,
    SFC_OPERATION_SWITCH,
    SFC_OPERATION_MERGE
} SFCOperation;